package com.suning.sawp.service.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * 
 * 〈一句话功能简述〉<br> 
 * 〈功能详细描述〉HTTP
 *
 * @author root
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
public class HttpVGSClient {
    public static final String DEFAULT_CONTENTTYPE = "text/xml";

    private static final Logger LOGGER = LoggerFactory.getLogger(HttpVGSClient.class);

    private String url;

    private String data;

    private String method;

    private String contentType = "text/xml";

    private int timeout = 10 * 1000;

    private boolean needProxy;

    private String proxyIp;

    private String proxyPort;
    
    private String authorization;

    /**
     * 
     * @param url
     * @param contentType
     */
    public HttpVGSClient(String url, String contentType) {
        this.url = url;
        this.contentType = contentType;
    }

    /**
     * 
     * @param url
     * @param contentType
     * @param needProxy
     */
    public HttpVGSClient(String url, String contentType, boolean needProxy) {
        this.url = url;
        this.contentType = contentType;
        this.needProxy = needProxy;
    }
    
    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param data
     * @param url
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public String postResquest(String data, String url) {
        // 设置超时
        HttpParams params = new BasicHttpParams();
        HttpConnectionParams.setConnectionTimeout(params, this.timeout);
        HttpConnectionParams.setSoTimeout(params, this.timeout);
        HttpClient httpclient = new DefaultHttpClient(params);
        
        try {
            if (needProxy) {
                HttpHost proxy = new HttpHost(proxyIp, Integer.parseInt(proxyPort));
                httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
            }
            LOGGER.debug("requestXml---------------:" + data);
            LOGGER.debug("url---------------:" + url);
            HttpPost httppost = new HttpPost(url);
            httppost.addHeader("Content-Type", contentType);
            httppost.addHeader("Authorization", authorization);//"IP 10.10.0.1"

            StringEntity reqEntity = new StringEntity(data, "UTF-8");
            httppost.setEntity(reqEntity);
            reqEntity.setContentType("text/xml; charset=UTF-8");
            LOGGER.debug("executing request " + httppost.getRequestLine());
            LOGGER.debug(httppost.getMethod() + "-------" + httppost.containsHeader("Content-Type"));
            HttpResponse response = httpclient.execute(httppost);
            HttpEntity resEntity = response.getEntity();

            LOGGER.debug("----------------------------------------");
            LOGGER.debug(response.getStatusLine().toString());
            if (resEntity != null) {
                LOGGER.debug("Response content length: " + resEntity.getContentLength() + "---"
                        + response.getFirstHeader("Content-Type"));
            }
            String responseXml = readResponse(resEntity);
            //调成debug模式
            LOGGER.debug("ResponseXml-----------: " + responseXml);

            return responseXml;
        } catch (SocketException e) {
            LOGGER.error("SocketException : ", e);
        } catch (UnsupportedEncodingException e) {
            LOGGER.error("UnsupportedEncodingException : ", e);
        } catch (ParseException e) {
            LOGGER.error("ParseException : ", e);
        } catch (IOException e) {
            LOGGER.error("IOException : ", e);
        } finally {
            httpclient.getConnectionManager().shutdown(); // commented by MST:
                                                          // This method might
                                                          // ignore an exception
        }
        return null;
    }
    
    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param data
     * @param url
     * @param isNeedPoxy
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public String ppmDevPostRequestData(String data, String url, boolean isNeedPoxy) {
     // 设置超时
        HttpParams params = new BasicHttpParams();
        HttpConnectionParams.setConnectionTimeout(params, this.timeout);
        HttpConnectionParams.setSoTimeout(params, this.timeout);
        HttpClient httpclient = new DefaultHttpClient(params);
        
        try {
            if (isNeedPoxy) {
                HttpHost proxy = new HttpHost(proxyIp, Integer.parseInt(proxyPort));
                httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
            }
            LOGGER.debug("requestXml---------------:" + data);
            LOGGER.debug("url---------------:" + url);
            HttpPost httppost = new HttpPost(url);
            httppost.addHeader("Content-Type", contentType);
            httppost.addHeader("Authorization", authorization);//"IP 10.10.0.1"

            StringEntity reqEntity = new StringEntity(data, "UTF-8");
            httppost.setEntity(reqEntity);
            reqEntity.setContentType("text/xml; charset=UTF-8");
            LOGGER.debug("executing request " + httppost.getRequestLine());
            LOGGER.debug(httppost.getMethod() + "-------" + httppost.containsHeader("Content-Type"));
            HttpResponse response = httpclient.execute(httppost);
            HttpEntity resEntity = response.getEntity();

            LOGGER.debug("----------------------------------------");
            LOGGER.debug(response.getStatusLine().toString());
            if (resEntity != null) {
                LOGGER.debug("Response content length: " + resEntity.getContentLength() + "---"
                        + response.getFirstHeader("Content-Type"));
            }
            String responseXml = readResponse(resEntity);
            //调成debug模式
            LOGGER.debug("ResponseXml-----------: " + responseXml);

            return responseXml;
        } catch (SocketException e) {
            LOGGER.error("SocketException : ", e);
        } catch (UnsupportedEncodingException e) {
            LOGGER.error("UnsupportedEncodingException : ", e);
        } catch (ParseException e) {
            LOGGER.error("ParseException : ", e);
        } catch (IOException e) {
            LOGGER.error("IOException : ", e);
        } finally {
            httpclient.getConnectionManager().shutdown(); // commented by MST:
                                                          // This method might
                                                          // ignore an exception
        }
        return null;
    }
    
    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param data
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public String postRequestData(String data) {

       return this.postResquest(data, url);
    }

    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param data
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public String postFormDataThrowHttps(String data) {

        // 设置超时
        HttpParams params = new BasicHttpParams();
        HttpConnectionParams.setConnectionTimeout(params, this.timeout);
        HttpConnectionParams.setSoTimeout(params, this.timeout);
        HttpClient httpclient = new DefaultHttpClient(params);
        httpclient = wrapClient(httpclient);
        try {
            if (needProxy) {
                HttpHost proxy = new HttpHost(proxyIp, Integer.parseInt(proxyPort));
                httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
            }

            HttpPost httppost = new HttpPost(url);
            List<NameValuePair> qparams = new ArrayList<NameValuePair>();
            qparams.add(new BasicNameValuePair("xml", data));
            UrlEncodedFormEntity entity = new UrlEncodedFormEntity(qparams, "UTF-8");

            httppost.setEntity(entity);

            LOGGER.debug("executing request " + httppost.getRequestLine());
            LOGGER.debug(httppost.getMethod() + "-----------"
                    + httppost.containsHeader("Content-Type"));
            LOGGER.debug("requestXml---------------:" + EntityUtils.toString(httppost.getEntity()));
            HttpResponse response = httpclient.execute(httppost);
            HttpEntity resEntity = response.getEntity();

            LOGGER.debug("----------------------------------------");
            LOGGER.debug(response.getStatusLine().toString());
            if (resEntity != null) {
                LOGGER.debug("Response content length: " + resEntity.getContentLength() + "---"
                        + response.getFirstHeader("Content-Type"));
            }
            String responseXml = readResponse(resEntity);
            LOGGER.debug("ResponseXml-----------: " + responseXml);
            return responseXml;
        } catch (SocketException e) {
            LOGGER.error("SocketException : ", e);
        } catch (UnsupportedEncodingException e) {
            LOGGER.error("UnsupportedEncodingException : ", e);
        } catch (ParseException e) {
            LOGGER.error("ParseException : ", e);
        } catch (IOException e) {
            LOGGER.error("IOException : ", e);
        } finally {
            httpclient.getConnectionManager().shutdown();
        }
        return null;
    }

    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param base
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    @SuppressWarnings("deprecation")
    private HttpClient wrapClient(HttpClient base) {
        try {
            SSLContext ctx = SSLContext.getInstance("TLS");
            X509TrustManager tm = new X509TrustManager() {

                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                public void checkClientTrusted(java.security.cert.X509Certificate[] chain,
                        String authType) throws java.security.cert.CertificateException {
                }

                public void checkServerTrusted(java.security.cert.X509Certificate[] chain,
                        String authType) throws java.security.cert.CertificateException {
                }
            };
            ctx.init(null, new TrustManager[] { tm }, null);
            SSLSocketFactory ssf = new SSLSocketFactory(ctx);
            ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            ClientConnectionManager ccm = base.getConnectionManager();
            SchemeRegistry sr = ccm.getSchemeRegistry();
            sr.register(new Scheme("https", ssf, 443));
            return new DefaultHttpClient(ccm, base.getParams());
        } catch (Exception e) {
            LOGGER.error("", e);
            return null;
        }
    }

    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param resEntity
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    @SuppressWarnings("deprecation")
    private static String readResponse(HttpEntity resEntity) {
        StringBuffer res = new StringBuffer();
        try {
            if (resEntity == null) {
                LOGGER.error("read null response in readResponse() method");
                return ""; // add by MST to avoid null pointer issue, can
                           // rewrite here according to business req
            }
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    resEntity.getContent(), "utf-8"));
            String line = null;
            while ((line = reader.readLine()) != null) {
                res.append(line);
            }
            resEntity.consumeContent();
            reader.close();
        } catch (Exception e) {
            LOGGER.error("", e);
        }
        return res.toString();
    }

    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public String getUrl() {
        return url;
    }

    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param url
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public void setUrl(String url) {
        this.url = url;
    }

    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public String getData() {
        return data;
    }

    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param data
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public void setData(String data) {
        this.data = data;
    }

    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public String getMethod() {
        return method;
    }

    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param method
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public void setMethod(String method) {
        this.method = method;
    }

    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public String getContentType() {
        return contentType;
    }

    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param contentType
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public void setContentType(String contentType) {
        this.contentType = contentType;
    }

    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public int getTimeout() {
        return timeout;
    }

    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param timeout
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public boolean isNeedProxy() {
        return needProxy;
    }

    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param needProxy
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public void setNeedProxy(boolean needProxy) {
        this.needProxy = needProxy;
    }

    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public String getProxyIp() {
        return proxyIp;
    }

    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param proxyIp
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public void setProxyIp(String proxyIp) {
        this.proxyIp = proxyIp;
    }

    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public String getProxyPort() {
        return proxyPort;
    }

    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param proxyPort
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public void setProxyPort(String proxyPort) {
        this.proxyPort = proxyPort;
    }

    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public String getAuthorization() {
        return authorization;
    }

    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param authorization
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public void setAuthorization(String authorization) {
        this.authorization = authorization;
    }

}
